const { DataTypes } = require('sequelize')
const { sequelize } = require('../config/database')
const { SYSTEM_CONFIG_KEYS, ERROR_CODES } = require('../utils/constants')
const logger = require('../utils/logger')
const { encrypt, decrypt } = require('../utils/crypto')

const SystemConfig = sequelize.define('SystemConfig', {
  id: {
    type: DataTypes.UUID,
    defaultValue: DataTypes.UUIDV4,
    primaryKey: true
  },
  key: {
    type: DataTypes.STRING(100),
    allowNull: false,
    unique: true,
    validate: {
      notEmpty: true
    }
  },
  value: {
    type: DataTypes.TEXT,
    allowNull: true
  },
  type: {
    type: DataTypes.ENUM('string', 'number', 'boolean', 'json', 'array'),
    defaultValue: 'string'
  },
  isEncrypted: {
    type: DataTypes.BOOLEAN,
    defaultValue: false
  },
  isPublic: {
    type: DataTypes.BOOLEAN,
    defaultValue: false
  },
  description: {
    type: DataTypes.TEXT,
    allowNull: true
  },
  category: {
    type: DataTypes.STRING(50),
    allowNull: true
  },
  isActive: {
    type: DataTypes.BOOLEAN,
    defaultValue: true
  },
  metadata: {
    type: DataTypes.JSON,
    allowNull: true
  }
}, {
  tableName: 'system_configs',
  timestamps: true,
  indexes: [
    {
      fields: ['key']
    },
    {
      fields: ['category']
    },
    {
      fields: ['isActive']
    },
    {
      fields: ['isPublic']
    }
  ]
})

class SystemConfigService {
  constructor() {
    this.cache = new Map()
    this.cacheExpiry = new Map()
  }

  /**
   * 获取配置值
   */
  async get(key, defaultValue = null) {
    // 检查缓存
    if (this.cache.has(key) && this.isCacheValid(key)) {
      return this.cache.get(key)
    }

    const config = await SystemConfig.findOne({ where: { key } })
    
    if (!config) {
      return defaultValue
    }

    let value = config.value
    
    // 如果是加密配置，需要解密
    if (config.isEncrypted) {
      try {
        value = decrypt(value)
      } catch (error) {
        logger.error('Failed to decrypt config value', { key, error: error.message })
        return defaultValue
      }
    }

    // 根据类型转换值
    value = this.parseValue(value, config.type)
    
    // 缓存结果
    this.setCache(key, value)
    
    return value
  }

  /**
   * 设置配置值
   */
  async set(key, value, options = {}) {
    const {
      type = 'string',
      isEncrypted = false,
      isPublic = false,
      description = null,
      category = null
    } = options

    // 验证配置键
    if (!this.isValidConfigKey(key)) {
      throw new Error(`Invalid config key: ${key}`)
    }

    // 验证值
    this.validateValue(key, value, type)

    let processedValue = this.stringifyValue(value, type)
    
    // 如果需要加密
    if (isEncrypted) {
      try {
        processedValue = encrypt(processedValue)
      } catch (error) {
        logger.error('Failed to encrypt config value', { key, error: error.message })
        throw new Error('Failed to encrypt config value')
      }
    }

    const [config, created] = await SystemConfig.upsert({
      key,
      value: processedValue,
      type,
      isEncrypted,
      isPublic,
      description,
      category
    })

    // 清除缓存
    this.clearCache(key)
    
    logger.info(`Config ${created ? 'created' : 'updated'}`, { key, type })
    
    return config
  }

  /**
   * 删除配置
   */
  async remove(key) {
    const result = await SystemConfig.destroy({ where: { key } })
    
    if (result === 0) {
      return false
    }

    // 清除缓存
    this.clearCache(key)
    
    logger.info('Config removed', { key })
    return true
  }

  /**
   * 获取所有配置
   */
  async getAll(options = {}) {
    const {
      includeEncrypted = false,
      publicOnly = false,
      category = null
    } = options

    const whereClause = {}
    
    if (publicOnly) {
      whereClause.isPublic = true
    }
    
    if (category) {
      whereClause.category = category
    }

    const configs = await SystemConfig.findAll({ where: whereClause })
    
    const result = {}
    
    for (const config of configs) {
      let value = config.value
      
      // 处理加密配置
      if (config.isEncrypted) {
        if (!includeEncrypted) {
          continue // 跳过加密配置
        }
        try {
          value = decrypt(value)
        } catch (error) {
          logger.error('Failed to decrypt config value', { key: config.key, error: error.message })
          continue
        }
      }
      
      result[config.key] = this.parseValue(value, config.type)
    }
    
    return result
  }

  /**
   * 获取公开配置
   */
  async getPublicConfigs() {
    return this.getAll({ publicOnly: true })
  }

  /**
   * 批量设置配置
   */
  async setBatch(configs) {
    const results = []
    
    for (const [key, configData] of Object.entries(configs)) {
      try {
        const result = await this.set(key, configData.value, configData.options || {})
        results.push({ key, success: true, result })
      } catch (error) {
        results.push({ key, success: false, error: error.message })
      }
    }
    
    return results
  }

  /**
   * 重置配置为默认值
   */
  async resetToDefault(key) {
    const defaultValue = this.getDefaultValue(key)
    const defaultOptions = this.getDefaultOptions(key)
    
    if (defaultValue !== undefined) {
      return this.set(key, defaultValue, defaultOptions)
    }
    
    return this.remove(key)
  }

  /**
   * 重置所有配置为默认值
   */
  async resetAllToDefault() {
    const results = []
    
    // 删除所有现有配置
    await SystemConfig.destroy({ where: {} })
    
    // 设置默认配置
    for (const key of Object.values(SYSTEM_CONFIG_KEYS)) {
      try {
        const defaultValue = this.getDefaultValue(key)
        const defaultOptions = this.getDefaultOptions(key)
        
        if (defaultValue !== undefined) {
          const result = await this.set(key, defaultValue, defaultOptions)
          results.push({ key, success: true, result })
        }
      } catch (error) {
        results.push({ key, success: false, error: error.message })
      }
    }
    
    // 清除所有缓存
    this.clearAllCache()
    
    return results
  }

  /**
   * 导出配置
   */
  async exportConfigs(options = {}) {
    const {
      includeEncrypted = false,
      categories = null
    } = options

    const whereClause = {}
    if (categories) {
      whereClause.category = categories
    }

    const configs = await SystemConfig.findAll({ where: whereClause })
    
    const exportData = {
      version: '1.0',
      exportedAt: new Date().toISOString(),
      configs: {}
    }
    
    for (const config of configs) {
      if (config.isEncrypted && !includeEncrypted) {
        continue
      }
      
      exportData.configs[config.key] = {
        value: config.value,
        type: config.type,
        isEncrypted: config.isEncrypted,
        isPublic: config.isPublic,
        description: config.description,
        category: config.category
      }
    }
    
    return exportData
  }

  /**
   * 导入配置
   */
  async importConfigs(configData, options = {}) {
    const {
      overwrite = false,
      validateKeys = true
    } = options

    if (!configData.configs) {
      throw new Error('Invalid config data format')
    }

    const results = []
    
    for (const [key, config] of Object.entries(configData.configs)) {
      try {
        // 验证配置键
        if (validateKeys && !this.isValidConfigKey(key)) {
          results.push({ key, success: false, error: 'Invalid config key' })
          continue
        }

        // 检查是否已存在
        if (!overwrite) {
          const existing = await SystemConfig.findOne({ where: { key } })
          if (existing) {
            results.push({ key, success: false, error: 'Config already exists' })
            continue
          }
        }

        const result = await this.set(key, config.value, {
          type: config.type,
          isEncrypted: config.isEncrypted,
          isPublic: config.isPublic,
          description: config.description,
          category: config.category
        })
        
        results.push({ key, success: true, result })
      } catch (error) {
        results.push({ key, success: false, error: error.message })
      }
    }
    
    return results
  }

  /**
   * 获取配置历史（简化版本）
   */
  async getConfigHistory(key, limit = 10) {
    // 由于Sequelize模型没有内置历史记录，这里返回当前配置
    const config = await SystemConfig.findOne({ where: { key } })
    return config ? [config] : []
  }

  /**
   * 验证配置值
   */
  validateValue(key, value, type) {
    switch (type) {
      case 'string':
        if (typeof value !== 'string') {
          throw new Error(`Config ${key} must be a string`)
        }
        break
      case 'number':
        if (typeof value !== 'number' || isNaN(value)) {
          throw new Error(`Config ${key} must be a number`)
        }
        break
      case 'boolean':
        if (typeof value !== 'boolean') {
          throw new Error(`Config ${key} must be a boolean`)
        }
        break
      case 'json':
      case 'array':
        if (typeof value !== 'object') {
          throw new Error(`Config ${key} must be an object`)
        }
        break
      default:
        throw new Error(`Invalid config type: ${type}`)
    }
  }

  /**
   * 解析配置值
   */
  parseValue(value, type) {
    if (value === null || value === undefined) {
      return value
    }

    switch (type) {
      case 'string':
        return String(value)
      case 'number':
        return Number(value)
      case 'boolean':
        return value === 'true' || value === true
      case 'json':
      case 'array':
        return typeof value === 'string' ? JSON.parse(value) : value
      default:
        return value
    }
  }

  /**
   * 字符串化配置值
   */
  stringifyValue(value, type) {
    switch (type) {
      case 'json':
      case 'array':
        return JSON.stringify(value)
      default:
        return String(value)
    }
  }

  /**
   * 验证配置键是否有效
   */
  isValidConfigKey(key) {
    return Object.values(SYSTEM_CONFIG_KEYS).includes(key) ||
           /^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(key)
  }

  /**
   * 获取默认值
   */
  getDefaultValue(key) {
    const defaults = {
      [SYSTEM_CONFIG_KEYS.SITE_NAME]: 'Vue Knowledge Base',
      [SYSTEM_CONFIG_KEYS.SITE_DESCRIPTION]: 'A comprehensive Vue.js learning platform',
      [SYSTEM_CONFIG_KEYS.MAINTENANCE_MODE]: false,
      [SYSTEM_CONFIG_KEYS.REGISTRATION_ENABLED]: true,
      [SYSTEM_CONFIG_KEYS.EMAIL_VERIFICATION_REQUIRED]: false,
      [SYSTEM_CONFIG_KEYS.MAX_UPLOAD_SIZE]: 10485760, // 10MB
      [SYSTEM_CONFIG_KEYS.SESSION_TIMEOUT]: 3600, // 1 hour
      [SYSTEM_CONFIG_KEYS.PASSWORD_MIN_LENGTH]: 6,
      [SYSTEM_CONFIG_KEYS.AI_DEFAULT_MODEL]: 'gpt-3.5-turbo',
      [SYSTEM_CONFIG_KEYS.AI_MAX_TOKENS]: 2000,
      [SYSTEM_CONFIG_KEYS.CHAT_HISTORY_LIMIT]: 100
    }
    
    return defaults[key]
  }

  /**
   * 获取默认选项
   */
  getDefaultOptions(key) {
    const options = {
      [SYSTEM_CONFIG_KEYS.SITE_NAME]: { type: 'string', isPublic: true, category: 'general' },
      [SYSTEM_CONFIG_KEYS.SITE_DESCRIPTION]: { type: 'string', isPublic: true, category: 'general' },
      [SYSTEM_CONFIG_KEYS.MAINTENANCE_MODE]: { type: 'boolean', isPublic: true, category: 'system' },
      [SYSTEM_CONFIG_KEYS.REGISTRATION_ENABLED]: { type: 'boolean', isPublic: true, category: 'auth' },
      [SYSTEM_CONFIG_KEYS.EMAIL_VERIFICATION_REQUIRED]: { type: 'boolean', category: 'auth' },
      [SYSTEM_CONFIG_KEYS.MAX_UPLOAD_SIZE]: { type: 'number', category: 'upload' },
      [SYSTEM_CONFIG_KEYS.SESSION_TIMEOUT]: { type: 'number', category: 'auth' },
      [SYSTEM_CONFIG_KEYS.PASSWORD_MIN_LENGTH]: { type: 'number', category: 'auth' },
      [SYSTEM_CONFIG_KEYS.AI_DEFAULT_MODEL]: { type: 'string', category: 'ai' },
      [SYSTEM_CONFIG_KEYS.AI_MAX_TOKENS]: { type: 'number', category: 'ai' },
      [SYSTEM_CONFIG_KEYS.CHAT_HISTORY_LIMIT]: { type: 'number', category: 'chat' }
    }
    
    return options[key] || {}
  }

  /**
   * 设置缓存
   */
  setCache(key, value, ttl = 300000) { // 5分钟默认TTL
    this.cache.set(key, value)
    this.cacheExpiry.set(key, Date.now() + ttl)
  }

  /**
   * 清除缓存
   */
  clearCache(key) {
    this.cache.delete(key)
    this.cacheExpiry.delete(key)
  }

  /**
   * 检查缓存是否有效
   */
  isCacheValid(key) {
    return this.cacheExpiry.has(key) && Date.now() < this.cacheExpiry.get(key)
  }

  /**
   * 清除所有缓存
   */
  clearAllCache() {
    this.cache.clear()
    this.cacheExpiry.clear()
  }

  /**
   * 获取统计信息
   */
  async getStats() {
    const total = await SystemConfig.count()
    const byCategory = await SystemConfig.findAll({
      attributes: [
        'category',
        [sequelize.fn('COUNT', sequelize.col('id')), 'count']
      ],
      group: ['category']
    })
    const encrypted = await SystemConfig.count({ where: { isEncrypted: true } })
    const publicConfigs = await SystemConfig.count({ where: { isPublic: true } })
    
    return {
      total,
      encrypted,
      public: publicConfigs,
      byCategory: byCategory.reduce((acc, item) => {
        acc[item.category || 'uncategorized'] = parseInt(item.dataValues.count)
        return acc
      }, {}),
      cacheSize: this.cache.size
    }
  }
}

module.exports = new SystemConfigService()